// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: implementation of CXFormsParseSelection.
//   $Id$


#include "stdafx.h"
#include "parseSelection.h"
#include "select.h"
#include "FP_Definitions.h"
#include "BinaryBehavior.h"
#include "ImplContextualValue.h"
#include "XFormsXFormsElement.h"
#include "tags.h"
#include "itemset.h"
#include "choices.h"
#include "item.h"
#include "XFormsElement.h"
CXFormsParseSelection::CXFormsParseSelection(CImplSelection* pImpl)
		: CXFormsParseFormControlInput(pImpl)
{
	addAttributeCheck(ATTR_SELECTION, &pImpl->m_sSelection);
};

CXFormsParseSelectOne::CXFormsParseSelectOne(CImplSelectOne* pImpl)
	: CXFormsParseSelection( pImpl)
{
};

CXFormsParseChoices::CXFormsParseChoices(CImplChoices* pImpl)
	: CXFormsParse(pImpl)
{
};

CXFormsParseValue::CXFormsParseValue(CImplValue* pImpl)
	: CXFormsParseSingleNodeBinding(static_cast<CImplSingleNodeBinding*>(pImpl))
{
	m_psImplContent = &pImpl->m_sContent;
};

CXFormsParseCopy::CXFormsParseCopy(CImplCopy* pImpl)
	: CXFormsParseSingleNodeBinding(static_cast<CImplSingleNodeBinding*>(pImpl))
{

};


CXFormsParseItemset::CXFormsParseItemset(CImplItemset* pImpl)
	: CXFormsParseNodesetBinding(pImpl)
{
};

CXFormsParseItem::CXFormsParseItem(CImplItem* pImpl)
	: CXFormsParse( pImpl)
{
};


/*
 * CXFormsParseSelection handles the common parsing for all selection form controls
 */

#include "parseLabel.h"
#include "parseAlert.h"
#include "commonChild.h"
#include "choices.h"
#include "item.h"
void CXFormsParseSelection::CheckElement(IHTMLElement *pElem, BSTR sTag, CImpl* pImpl)
{
	HRESULT hr = S_OK;
	if ( TAG_CHOICES == sTag)
	{
		CImplChoices* pChoices = new CImplChoices();
		CXFormsParseChoices parse(pChoices);
		pChoices->m_pXForms = pImpl->m_pXForms;
		hr = parse.Parse(pElem, pChoices);
		if (S_OK == hr)
			hr = pChoices->init(pImpl);

		((CImplSelection*) pImpl)->AddItem(pChoices);
	}

	else if (TAG_ITEM == sTag || TAG_ITEMSET == sTag)
	{
		/*
		CImplItem* pItem = new CImplItem();
		CXFormsParseItem parse(pItem);
		pItem->m_pXForms = pImpl->m_pXForms;
		hr = parse.Parse(pElem, pItem);
		*/
		CComPtr<IElementBehavior> pBehavior;
		CBinaryBehavior::GetNamedBehavior(g_bsAttrXFormsElementController,pElem,&pBehavior);
		
		if(pBehavior)
		{
			CImpl * pImplItem = 0;
			//Attempt to fetch pImplItem by casting to CXFormsElement

			CXFormsElement * pBehaviourAsXFormsElement = dynamic_cast<CXFormsElement *>(pBehavior.p);
			if(pBehaviourAsXFormsElement)
			{
				 hr = pBehaviourAsXFormsElement->get_Impl(&pImplItem);
			}
			else
				hr = pImpl->m_pXForms->GetParentImpl(pBehavior,&pImpl);

			if(pImplItem && S_OK == hr)
			{
				CImplItem* pItem = dynamic_cast<CImplItem*>(pImplItem);
			
				if (pItem)
				{
					hr = pItem->init(pImpl);
					((CImplSelection*) pImpl)->AddItem(pItem);
				}
				else
				{
					CImplItemset* pItemset = dynamic_cast<CImplItemset*>(pImplItem);
				
					if (pItemset)
					{
						((CImplSelection*) pImpl)->AddItem(pItemset);
					}
				}
			}

		}
	
	}

	else
	{
		CXFormsParseFormControlInput::CheckElement(pElem, sTag, pImpl);
	}
}



/*
 * CXFormsParseChoices
 */

void CXFormsParseChoices::CheckElement(IHTMLElement *pElem, BSTR sTag, CImpl* pImpl)
{
	HRESULT hr = S_OK;

	if (TAG_CAPTION == sTag)
	{
		CImplCaption* pCaption = new CImplCaption();
		CXFormsParseCaption parse(pCaption);

		hr = parse.Parse(pElem, pCaption);
		if (S_OK == hr)
			hr = pCaption->init(pImpl);

		((CImplChoices*) pImpl)->m_pCaption = pCaption;
	}

	else if (TAG_CHOICES == sTag)
	{
		CImplChoices* pChoices = new CImplChoices();
		CXFormsParseChoices parse(pChoices);
		pChoices->m_pXForms = pImpl->m_pXForms;

		hr = parse.Parse(pElem, pChoices);
		if (S_OK == hr)
			hr = pChoices->init(pImpl);

		((CImplChoices*) pImpl)->AddItem(pChoices);
	}

	else if (TAG_ITEM == sTag || TAG_ITEMSET  == sTag)
	{
		CComPtr<IElementBehavior> pBehavior;
		CBinaryBehavior::GetNamedBehavior(g_bsAttrXFormsElementController,pElem,&pBehavior);
		
		if(pBehavior)
		{
			CImpl * pImplItem = 0;
			CXFormsElement * pBehaviourAsXFormsElement = dynamic_cast<CXFormsElement *>(pBehavior.p);
			if(pBehaviourAsXFormsElement)
			{
				hr = pBehaviourAsXFormsElement->get_Impl(&pImplItem);
			}
			else
				hr = pImpl->m_pXForms->GetParentImpl(pBehavior,&pImpl);

			if(pImplItem && S_OK == hr)
			{
				CImplItem* pItem = dynamic_cast<CImplItem*>(pImplItem);
			
				if (pItem)
				{
					hr = pItem->init(pImpl);
					((CImplChoices*) pImpl)->AddItem(pItem);
				}
				else
				{
					CImplItemset* pItemset = dynamic_cast<CImplItemset*>(pImplItem);
				
					if (pItemset)
					{
						hr = pItemset->init(pImpl);
						((CImplChoices*) pImpl)->AddItem(pItemset);
					}
				}
			}

		}
	}
}

/*
 * CXFormsParseItem
 */

CXFormsParseItem::~CXFormsParseItem()
{

}

void CXFormsParseItem::CheckElement(IHTMLElement *pElem, BSTR sTag, CImpl* pImpl)
{
	HRESULT hr = S_OK;
	if ( TAG_CAPTION == sTag)
	{
		CImplCaption* pCaption = new CImplCaption();
		CXFormsParseCaption parse(pCaption);
		pCaption->m_pXForms = pImpl->m_pXForms;
		hr = parse.Parse(pElem, pCaption);
		if (S_OK == hr)
		{
			pCaption->m_pParentImpl = pImpl->m_pParentImpl;
			hr = pCaption->init(pImpl);
		}

		((CImplItem*) pImpl)->m_pCaption = pCaption;
	}

	else if (TAG_VALUE == sTag)
	{
		CImplValue* pValue = new CImplValue();
		CXFormsParseValue parse(pValue);
		pValue->m_pXForms = pImpl->m_pXForms;
		hr = parse.Parse(pElem, pValue);
		if (S_OK == hr)
		{
			pValue->m_pParentImpl = pImpl->m_pParentImpl;
			hr = pValue->init(pImpl);
		}

		((CImplItem*) pImpl)->m_pValue = pValue;
	}

	/*
	 * [TODO]
	 * Put this lot into a function
	 */


	else if (TAG_ALERT == sTag)
	{
		CImplAlert* pAlert = new CImplAlert();
		CXFormsParseAlert parse(pAlert);
		pAlert->m_pXForms = pImpl->m_pXForms;

		hr = parse.Parse(pElem, pAlert);
		if (S_OK == hr)
			hr = pAlert->init(pImpl);

		((CImplItem*) pImpl)->m_pAlert = pAlert;
	}

}



void CXFormsParseItemset::CheckElement(IHTMLElement *pElem, BSTR sTag, CImpl* pImpl)
{
	HRESULT hr = S_OK;
	if (TAG_CAPTION == sTag)
	{
		CImplContextualValue * pCV = new CImplContextualValue();
		CComVariant vtTemp;
		pElem->getAttribute(L"ref",1,&vtTemp);
		if(vtTemp.vt == VT_BSTR)
		{
			vtTemp.CopyTo(&pCV->m_sValueExpression);
		}
		pElem->get_innerHTML(&pCV->m_sSimpleValue);
		if(!pCV->m_sValueExpression && !pCV->m_sSimpleValue)
		{
			pCV->m_sValueExpression = L".";
		}
		CImplItemset * pItemset = dynamic_cast<CImplItemset*>(pImpl);
		pItemset->m_pCaption = pCV;
	
	}
	else if ( TAG_VALUE == sTag)
	{
		CImplContextualValue * pCV = new CImplContextualValue();
		CComVariant vtTemp;
		pElem->getAttribute(L"ref",1,&vtTemp);
		if(vtTemp.vt == VT_BSTR)
		{
			vtTemp.CopyTo(&pCV->m_sValueExpression);
		}
		pElem->get_innerHTML(&pCV->m_sSimpleValue);
		if(!pCV->m_sValueExpression && !pCV->m_sSimpleValue)
		{
			pCV->m_sValueExpression = L".";
		}
		CImplItemset * pItemset = dynamic_cast<CImplItemset*>(pImpl);
		pItemset->m_pValue = pCV;

	}


/*	if (TAG_CAPTION == sTag)
	{
		CImplCaption* pCaption = new CImplCaption_passive();
		CXFormsParseCaption parse(pCaption);
		pCaption->m_pXForms = pImpl->m_pXForms;
		hr = parse.Parse(pElem, pCaption);
		if (S_OK == hr)
			hr = pCaption->init(pImpl);

		// Bug 240 - If there is already a caption associated with the itemset
		// detach the captions from it. So that on deletion of that object 
		// from the orphans list the caption will not try and detach again.
		CImplItemset * pItemset = static_cast<CImplItemset*> (pImpl);
		if(pItemset->m_pCaption)
		{
			pItemset->m_pCaption->m_pParent = 0;
			pItemset->detachCaption();
		}

		pItemset->m_pCaption = pCaption;
	}

	else if ( TAG_VALUE == sTag)
	{
		CImplValue* pValue = new CImplValue();
		CXFormsParseValue parse(pValue);
		pValue->m_pXForms = pImpl->m_pXForms;
		hr = parse.Parse(pElem, pValue);
		if (S_OK == hr)
			hr = pValue->init(pImpl);

		// If a value has already been attached release it
		CImplItemset * pItemset = static_cast<CImplItemset*> (pImpl);
		if(pItemset->m_pValue)
		{
			pItemset->m_pValue->m_pParent = 0;
		}

		pItemset->m_pValue = pValue;
	}
*/
	else if ( TAG_COPY == sTag)
	{
		CImplCopy* pCopy = new CImplCopy();
		CXFormsParseCopy parse(pCopy);
		pCopy->m_pXForms = pImpl->m_pXForms;
		hr = parse.Parse(pElem, pCopy);
		if (S_OK == hr)
			hr = pCopy->init(pImpl);

		// If a copy has already been attached then release it
		CImplItemset * pItemset = static_cast<CImplItemset*> (pImpl);
		if(pItemset->m_pCopy)
		{
			pItemset->m_pCopy->m_pParent = 0;
		}

		pItemset->m_pCopy = pCopy;
	}

	/*
	 * [TODO]
	 * Put this lot into a function
	 */

	else if (TAG_ALERT == sTag)
	{
		CImplAlert* pAlert = new CImplAlert();
		CXFormsParseAlert parse(pAlert);
		pAlert->m_pXForms = pImpl->m_pXForms;
		hr = parse.Parse(pElem, pAlert);
		if (S_OK == hr)
			hr = pAlert->init(pImpl);

		// If a alert has already been attached then release it
		CImplItemset * pItemset = static_cast<CImplItemset*> (pImpl);
		if(pItemset->m_pAlert)
		{
			pItemset->m_pAlert->m_pParent = 0;
			pItemset->detachAlert();
		}

		pItemset->m_pAlert = pAlert;
	}

}